package com.zrfintech.core.service.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import com.zrfintech.core.service.cache.CacheType;
import com.zrfintech.core.service.cache.InstitutionCache;
import com.zrfintech.core.service.cache.ProductCache;
import com.zrfintech.dao.entity.MgInstitutionEntity;
import com.zrfintech.dao.entity.MgProductEntity;
import com.zrfintech.dao.mapper.MgInstitutionEntityMapper;
import com.zrfintech.dao.mapper.MgProductEntityMapper;
import com.zrfintech.dao.mapper.MgProductInstitutionEntityMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ProductCacheTask {

    private static Logger LOGGER = LoggerFactory.getLogger(ProductCacheTask.class);

    @Autowired
    private MgProductEntityMapper mgProductEntityMapper;

    @Autowired
    private MgInstitutionEntityMapper mgInstitutionEntityMapper;

    @Autowired
    private MgProductInstitutionEntityMapper mgProductInstitutionEntityMapper;

//    @Scheduled(fixedRate = 5 * 1000) // 每5秒执行一次
    public void refreshCache() {
        LOGGER.info("productCache={}", JSONObject.toJSONString(ProductCache.ProductChcheMap));
        loadProduct();
        loadInst();
    }

    private static final Long DEFAULT_VALUE = -1L;

    private static Map<CacheType, Long> cacheTimeMap = Maps.newHashMap();

    static {
        cacheTimeMap.put(CacheType.PRODUCT, DEFAULT_VALUE);
        cacheTimeMap.put(CacheType.INSTITUTION, DEFAULT_VALUE);
        cacheTimeMap.put(CacheType.PRODUCT_INSTITUTION, DEFAULT_VALUE);
    }


    /**
     * 加载产品
     */
    private void loadProduct() {
        try {
            Long oldDate = cacheTimeMap.get(CacheType.PRODUCT);
            if (oldDate != null) {
                MgProductEntity newUpdate = mgProductEntityMapper.selectNewUpdateTime();
                if (null == newUpdate) {
                    ProductCache.ProductMap = Maps.newHashMap();
                    ProductCache.ProductChcheMap = Maps.newHashMap();
                    cacheTimeMap.put(CacheType.PRODUCT, DEFAULT_VALUE);
                } else {
                    long count = mgProductEntityMapper.selectCount(null);
                    long newDate = newUpdate.getUpdateTime().getTime() + count;
                    if (newDate != oldDate) {
                        Map<String, String> productMap = Maps.newHashMap();
                        Map<String, MgProductEntity> productCacheMap = Maps.newHashMap();
                        QueryWrapper<MgProductEntity> wrapper = new QueryWrapper<>();
                        wrapper.orderByDesc("update_time");
                        List<MgProductEntity> productList = mgProductEntityMapper.selectList(wrapper);
                        productList.forEach(product -> {
                            productMap.put(product.getProductId(), product.getProductName());
                            productCacheMap.put(product.getProductId(), product);
                        });
                        ProductCache.ProductMap = productMap;
                        ProductCache.ProductChcheMap = productCacheMap;
                        cacheTimeMap.put(CacheType.PRODUCT,
                                productList.get(0).getUpdateTime().getTime() + productList.size());
                        LOGGER.info("[loadProduct]Success load info={}.", JSON.toJSONString(productMap));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("[loadProduct]exception.", e);
        }
    }


    /**
     * 加载产品
     */
    private void loadInst() {
        try {
            Long oldDate = cacheTimeMap.get(CacheType.INSTITUTION);
            if (oldDate != null) {
                MgInstitutionEntity newUpdate = mgInstitutionEntityMapper.selectNewUpdateTime();
                if (null == newUpdate) {
                    InstitutionCache.institutionChcheMap = Maps.newHashMap();
                    cacheTimeMap.put(CacheType.INSTITUTION, DEFAULT_VALUE);
                } else {
                    long count = mgInstitutionEntityMapper.selectCount(null);
                    long newDate = newUpdate.getUpdateTime().getTime() + count;
                    if (newDate != oldDate) {
                        Map<String, MgInstitutionEntity> instCacheMap = Maps.newHashMap();
                        QueryWrapper<MgInstitutionEntity> wrapper = new QueryWrapper<>();
                        wrapper.orderByDesc("update_time");
                        List<MgInstitutionEntity> instList = mgInstitutionEntityMapper.selectList(wrapper);
                        instList.forEach(inst -> {
                            instCacheMap.put(inst.getInstitutionId(), inst);
                        });
                        InstitutionCache.institutionChcheMap = instCacheMap;
                        cacheTimeMap.put(CacheType.INSTITUTION,
                                instList.get(0).getUpdateTime().getTime() + instList.size());
                        LOGGER.info("[loadInst]Success load info={}.", JSON.toJSONString(instCacheMap));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("[loadInst]exception.", e);
        }
    }
}
